/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Servlet;

import DTO.ListPlaces;
import DTO.Place;
import DTO.Provinces;
import DTO.TagPointComparator;
import Utility.DBUtils;
import Utility.XMLUtils;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 *
 * @author TOSHIBA
 */
public class Controller extends HttpServlet {

    String filePath = "";
    boolean found = false;
    String fullname = "";
    final String welcomePage = "welcome.jsp";
    final String invalidPage = "invalid.html";

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String action = request.getParameter("btAction");
        if (action.equals("Submit")) { //Vo Hoang Thang -- Save Comment
            String Comment_Content = request.getParameter("txtComment");
            String nick = request.getParameter("txtNick");
            String CreateTime = String.valueOf(System.currentTimeMillis());
            int Place_ID = Integer.parseInt(request.getParameter("txtPlaceID"));
            Utility.CommentProcess.insertComment(nick, Comment_Content, CreateTime, Place_ID);
//                HttpSession session = request.getSession();
//                session.setAttribute("check", data.ultil.CommentProcess.total(1));
//                System.out.println(data.ultil.CommentProcess.total(1));
//                data.ultil.CommentProcess.marshallXML(filePath);
//                Thread.sleep(5000);
//                System.out.println(request.getParameter("total"));
            response.sendRedirect("PlaceDetail.jsp");
        } else if (action.equals("Delete")) {
            int id = Integer.parseInt(request.getParameter("Delete"));
            Utility.CommentProcess.deleteComment(id);
//                data.ultil.CommentProcess.marshallXML(filePath);
//                Thread.sleep(1000);
            response.sendRedirect("PlaceDetail.jsp");

        } else if (action.equals("Load")) {
            try {
                //Kiem tra xml da ton tai hay chua, neu chua thi load tu database.
                String appPath = getServletContext().getRealPath("/");
                filePath = appPath + "WEB-INF/XMLFiles/Provinces.xml";
                File f = new File(filePath);
                if (!f.exists()) {
                    //load Provinces len object
                    Provinces list = DBUtils.loadProvinced();
                    //Marshal tu object sang xml.
                    XMLUtils.JAXBMarshalling(list, filePath);
                }
                //Ket hop stylesheet de ghi du lieu ra man hinh
                response.sendRedirect("Convert.jsp");
            } catch (JAXBException ex) {
                
            }

        } else if (action.equals("toPlacePage")) {
            int provinceID = Integer.parseInt(request.getParameter("provinceID"));
            //load place va day sang html,mnbmn
            try {
                //get provinces list from db
                ListPlaces list = DBUtils.loadListPlacesbyProvinceID(provinceID);
                //parse into xml (luon luon parse, phai sua lai thanh thi thoang parse.
                //lay duong dan tuyet doi
                String appPath = getServletContext().getRealPath("/");
                filePath = appPath + "WEB-INF/XMLFiles/ListPlaces.xml";
                //parse into xml (luon luon parse, phai sua lai thanh thi thoang parse.
                XMLUtils.JAXBMarshalling(list, filePath);
                //Ket hop stylesheet de ghi du lieu ra man hinh
                response.sendRedirect("Convert.jsp?convertType=listPlacePage");
            } catch (JAXBException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex); //loi khi marshalling
            }

        } else if (action.equals("toPlaceDetail")) {
            try {
                //lay placeID tu request.
                int placeID = Integer.parseInt(request.getParameter("placeID"));

                //lay realpath
                String appPath = getServletContext().getRealPath("/");
                filePath = appPath + "WEB-INF/XMLFiles/Place" + placeID + ".xml";

                //kiem tra file xml da ton tai hay chua
                File f = new File(filePath);

                //object place de chua du lieu tu xml file.
                Place place;
                if (!f.exists()) { //neu chua ton tai thi khoi tao file xml.
                    //tao object tu database.
                    place = DBUtils.loadPlacebyPlaceID(placeID);
                    //marshall de tao file xml
                    XMLUtils.JAXBMarshalling(place, filePath);
                } else {
                    //do du lieu tu file xml len object
                    place = (Place) XMLUtils.JAXBUnmarshalling(Place.class, filePath);
                    Collections.sort(place.getTags().getTag(), new TagPointComparator());
                }

                //chuyen place vao session (khong dung request vi place con duoc su dung lai o duoi)
                HttpSession session = request.getSession();
                session.setAttribute("PLACE", place);
                RequestDispatcher rd = request.getRequestDispatcher("PlaceDetail.jsp");
                rd.forward(request, response);
            } catch (JAXBException ex) {
                //ex.printStackTrace();
                //nuot loi.
                response.sendRedirect("error.html");
            }
        } else if (action.equals("Like")) {
            try {
                int place_TagID = Integer.parseInt(request.getParameter("txtTag_Place_ID"));
                int newPoint = (Integer.parseInt(request.getParameter("txtPoint"))) + 1;
                int placeID = Integer.parseInt(request.getParameter("txtPlaceID"));
                //ham update value in xml DUNG DOM
                String appPath = getServletContext().getRealPath("/");
                String filePath = appPath + "WEB-INF/XMLFiles/" + "Place" + placeID + ".xml";
                Document doc = XMLUtils.parseDOMFromFile(filePath);
                String exp = "//tag[placeTagID='" + place_TagID + "']";
                Node result = (Node) XMLUtils.evaluteXPathExpression(doc, exp, XPathConstants.NODE);
                if (result != null) {
                    NodeList childrenNode = result.getChildNodes();
                    for (int i = 0; i < childrenNode.getLength(); i++) {
                        if (childrenNode.item(i).getNodeName().equals("point")) {
                            childrenNode.item(i).setTextContent(newPoint + "");
                            XMLUtils.transformDOMtoFile(doc, filePath);
                            //luu xuong database luon
                            DBUtils.updatePoint(place_TagID, (newPoint + 1));
                            //////////////////////////////////////////////////////////DEMO COOKIES
                            Cookie[] cookies = request.getCookies();
                            if (cookies == null) {
                                cookies = new Cookie[0];
                            }
                            String ptID = place_TagID + "";
//                            System.out.println("PT  ID____________________________"+ ptID);


                            for (int j = 0; j < cookies.length; j++) {
                                if (cookies[j].getName().equals(ptID)) {
                                    out.print("Exist");
                                    return;
                                }
                            }
                            Cookie added = null;
                            added = new Cookie(ptID, ptID);
                            response.addCookie(added);
                            added.setMaxAge(24 * 60 * 60);//save 1 ngay
                            out.print("Success");
                            return;
//
//                            for (int j = 0; j < cookies.length - 1; j++) {
//   System.out.println("Cookie Value Number :"+j+" and value "+cookies[j].getName());
//System.out.println("*******************************");
                            //                           }
                        }
                    }
                }
                //load database len lai tu dau hic hic
                //DBUtils.updatePoint(place_TagID, (newPoint+1));
                //load lai tu dau

            } catch (TransformerConfigurationException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            } catch (TransformerException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ParserConfigurationException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            } catch (SAXException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            } catch (XPathExpressionException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            }

        }  else if (action.equals("Rate")) { //nguoi su dung rate tag
            try {
                String place_tagID = request.getParameter("txtTag_Place_ID");
                //tang diem len 1
                int newPoint = (Integer.parseInt(request.getParameter("txtPoint"))) + 1;
                int placeID = Integer.parseInt(request.getParameter("txtPlaceID"));

                //lay cookies, neu khong co thi khoi tao
                Cookie[] cookies = request.getCookies();
                if (cookies == null) {
                    cookies = new Cookie[0];
                }

                //kiem tra da ton tai place_tagID trong cookie chua, neu co return.
                for (int j = 0; j < cookies.length; j++) {
                    if (cookies[j].getName().equals(place_tagID)) {
                        out.print("Exist");
                        return;
                    }
                }

                //Khi place_tagID chua ton tai trong cookie, update file xml dung DOM
                String appPath = getServletContext().getRealPath("/");
                String filePath = appPath + "WEB-INF/XMLFiles/" + "Place" + placeID + ".xml";
                //parse file xml thanh DOM.
                Document doc = XMLUtils.parseDOMFromFile(filePath);

                found = false;
                updatePointByPlaceTagID(doc, Integer.parseInt(place_tagID), newPoint);
                XMLUtils.transformDOMtoFile(doc, filePath);
                //luu xuong database luon (hi vong update duoc  thanh dong bo 15')
                DBUtils.updatePoint(Integer.parseInt(place_tagID), newPoint);
                //luu xong file thi add cookie
                Cookie added = null;
                added = new Cookie(place_tagID, place_tagID);
                added.setMaxAge(24 * 60 * 60);//save 1 ngay
                response.addCookie(added);
                out.print("Success");
                return;
                //Chuoi xpath dung de lay tag co placeTagID phu hop.
//                //String exp = "//tag[placeTagID='" + place_tagID + "']";
//
//                //dua tag phu hop vao node result
//                Node result = (Node) XMLUtils.evaluteXPathExpression(doc, exp, XPathConstants.NODE);
//
//
//                //Dung De Quy moi co diem
//                //Kiem tra dieu kien dung:
//
//
//
//
//                if (result != null) {
//                    NodeList childrenNode = result.getChildNodes();
//                    for (int i = 0; i < childrenNode.getLength(); i++) { //duyet con
//                        if (childrenNode.item(i).getNodeName().equals("point")) { //neu node name la point thi update value
//                            childrenNode.item(i).setTextContent(newPoint + "");
//                            //luu lai file xml
//                            XMLUtils.transformDOMtoFile(doc, filePath);
//                            //luu xuong database luon (hi vong update duoc  thanh dong bo 15')
//                            //DBUtils.updatePoint(Integer.parseInt(place_tagID), newPoint);
//                            //luu xong file thi add cookie
//                            Cookie added = null;
//                            added = new Cookie(place_tagID, place_tagID);
//                            added.setMaxAge(24 * 60 * 60);//save 1 ngay
//                            response.addCookie(added);
//                            out.print("Success");
//                            return;
//                        }
//                    }
//                }
            } catch (TransformerConfigurationException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            } catch (TransformerException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ParserConfigurationException ex) {
                //Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
                response.sendRedirect("error.html");
            } catch (SAXException ex) {
                //Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
                response.sendRedirect("error.html");
            }

        }
        try {
            //Demo do ra DOM
        } finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

     private void updatePointByPlaceTagID(Node node, int placeTagID, int newScore) {
        //kiem tra dieu kien dung
        if (node == null || found) {
            return;
        }
        //duyet cay dom
        if (node.getNodeName().equals("placeTagID")) {
            String place_tag_ID = node.getTextContent().trim();
            if (place_tag_ID.equals(placeTagID+"")) {
                found = true;
                Node pointNode = node.getPreviousSibling().getPreviousSibling();
                pointNode.setTextContent(newScore + "");
            }
        }
        //de quy
        NodeList children = node.getChildNodes();
        int i = 0;
        while (i < children.getLength()) {
            updatePointByPlaceTagID(children.item(i++), placeTagID, newScore);
        }
    }
}
